package services

import (
	"bytes"
	"crypto/tls"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/sirupsen/logrus"
	"io/ioutil"
	"net/http"
	"net/url"
	"regexp"
	"strconv"
	"strings"
	"time"
	"wecom_rebot/common"
	"wecom_rebot/core"
	"wecom_rebot/models"
)

var ksCopyAccountLogger *logrus.Logger

// InitKsCopyAccountLogger 移除 init() 函数，改为显式初始化函数
func InitKsCopyAccountLogger() {
	// 确保在 common 初始化后调用
	ksCopyAccountLogger = core.InitLogger(common.LogsErrorMap[19])
}

type KsAccount struct {
	SubjectName string
	AccountID   string
	CopyNumber  string
	Username    string
	OpenId      string
	UserId      string
	Code        string
	Email       string
}

type getKsBackgroundToken struct {
	Code int    `json:"code"`
	Msg  string `json:"msg"`
	Data struct {
		Token string `json:"token"`
	} `json:"data"`
	Result bool `json:"result"`
}

type ksResponse struct {
	Code      int             `json:"code"`
	Data      json.RawMessage `json:"data"`
	Message   string          `json:"message"`
	RequestId string          `json:"request_id"`
}

// CpRes 解析具体的 data 数据
type CpRes struct {
	NewAccountId   int    `json:"new_account_id"`
	Success        bool   `json:"success"`
	OldAccountId   int    `json:"old_account_id"`
	OldAccountName string `json:"old_account_name"`
	NewUserId      int    `json:"new_user_id"`
	NewAccountName string `json:"new_account_name"`
	NewUserName    string `json:"new_user_name"`
}

type DeftHandCopyAccountService struct{}

func (s *DeftHandCopyAccountService) Handle(msgId int, subjectName, roomId string, content []string, jobId uint64) error {
	strPj := "-----------------------------------"

	var msg = &models.Msg{}

	fmt.Println("ksCopyAccountLogger", "原始结构Id：", msgId)
	// 获取数据
	err := common.DB.Where("id = ?", msgId).First(&msg).Error
	if err != nil {
		ksCopyAccountLogger.Error("腾讯获取数据失败", common.LogsErrorMap[common.MysqlError], msgId, err)
		return err
	}

	ksCopyAccountLogger.Info("ksCopyAccountLogger", "原始结构：", content)

	// 处理需要的数据结构
	result, err := s.analyzeContent(content)
	if err != nil {
		ksCopyAccountLogger.Error(err)
		return err
	}

	ksCopyAccountLogger.Info("ksCopyAccountLogger", result)

	// 移除功能行
	msg.Content = RemoveTitle(msg)
	fmt.Println("移除后的结构：", msg, "广告主信息：", content)

	for _, item := range result {
		ksCopyAccountLogger.Info("获取整个item结果", item)
		var ks models.ImportKs
		err := common.DBDk.Where("account_id = ? AND is_old = 1", item.AccountID).First(&ks).Error
		if err != nil {
			return errors.New("未找到广告主ID信息" + item.AccountID + "请检查快手广告主表")
		}
		ksCopyAccountLogger.Info("查看快手广告主信息：", ks)

		if ks.Company != item.SubjectName {
			return errors.New("项目名称不匹配" + item.AccountID + "请检查快手广告主表")
		}

		// 获取对应后台ID的token
		token, err := getDeftHandToken(item.OpenId)
		if err != nil {
			return err
		}
		ksCopyAccountLogger.Info("token结果:", item)

		// 构造请求数据
		requestData := map[string]interface{}{
			"advertiser_id": item.AccountID,
			"agent_id":      item.OpenId,
			"account_list":  []string{item.AccountID},
			"user_id":       item.UserId,
			"code":          item.Code,
			"email":         item.Email,
			"uc_type":       "DSP_MAPI",
			"copy_number":   item.CopyNumber,
		}

		ksInfo, err := s.getKsCopyAccount(requestData, token)
		if err != nil {
			return err
		}
		ksCopyAccountLogger.Infof("快手复制账户返回结果: %v", ksInfo)

		// 处理返回结果
		var successAccountIds []int64
		var insertAllData []map[string]interface{}

		if len(ksInfo) > 0 {
			for _, v := range ksInfo {
				if !v.Success {
					// 复制失败，发送错误信息
					errorMsg := fmt.Sprintf("%s\n%s\n%s", msg.Content, strPj, "复制失败") // 这里需要根据实际错误信息调整
					if err := BendiSendText(errorMsg, msg.RoomID, msg.Sender); err != nil {
						return errors.New("复制失败：发送消息失败")
					}
					break
				} else {
					// 复制成功，收集成功账户ID
					successAccountIds = append(successAccountIds, int64(v.NewAccountId))

					// 准备插入数据库的数据
					insertData := map[string]interface{}{
						"parent":        item.AccountID,
						"account_id":    v.NewAccountId,
						"handle_status": 1,
						"type":          2,
						"created_at":    time.Now().Format("2006-01-02 15:04:05"),
						"username":      item.Username,
					}
					insertAllData = append(insertAllData, insertData)
				}
			}
		}

		// 去重处理
		uniqueInsertAllData := s.removeUniqueArray(insertAllData, "account_id")

		// 发送成功消息
		successMsg := fmt.Sprintf("%s\n%s\n复制成功数量：%d\n复制成功：%s",
			msg.Content,
			strPj,
			len(successAccountIds),
			strings.Join(s.int64SliceToStringSlice(successAccountIds), ","))

		if err := BendiSendText(successMsg, msg.RoomID, msg.Sender); err != nil {
			return errors.New("发送消息失败")
		}

		err = common.DB.Model(&models.CopyAccountList{}).Create(uniqueInsertAllData).Error
		if err != nil {
			return errors.New("数据入库异常，请检查日志: " + err.Error())
		}

		ksCopyAccountLogger.Infof("快手复制账户返回结果: %s", successMsg)
	}
	return nil
}

// removeUniqueArray 根据指定字段对map数组去重
func (s *DeftHandCopyAccountService) removeUniqueArray(data []map[string]interface{}, field string) []map[string]interface{} {
	seen := make(map[interface{}]bool)
	var result []map[string]interface{}

	for _, item := range data {
		if value, exists := item[field]; exists && !seen[value] {
			seen[value] = true
			result = append(result, item)
		}
	}

	return result
}

// int64SliceToStringSlice 将int64切片转换为字符串切片
func (s *DeftHandCopyAccountService) int64SliceToStringSlice(slice []int64) []string {
	var result []string
	for _, v := range slice {
		result = append(result, strconv.FormatInt(v, 10))
	}
	return result
}

func (s *DeftHandCopyAccountService) getKsCopyAccount(requestData interface{}, token string) ([]CpRes, error) {
	copyUrl := "https://ad.e.kuaishou.com/rest/openapi/gw/agent/v1/bind/copy/checkAndCopy"

	var req ksResponse
	// 发送请求
	err := KsSendCurlRequest(copyUrl, "POST", token, requestData, nil, &req)
	if err != nil {
		ksCopyAccountLogger.Errorf("快手复制账户请求失败: %v", err)
		return nil, errors.New("快手复制账户请求失败：" + err.Error())
	}

	ksCopyAccountLogger.Info("快手复制账户返回结果:", req)

	if req.Code != 0 {
		ksCopyAccountLogger.Errorf("快手复制账户失败: %v", req)
		return nil, errors.New("快手复制账户失败：" + req.Message)
	}

	var cp []CpRes

	if len(req.Data) > 0 {
		if err := json.Unmarshal(req.Data, &cp); err != nil {
			ksCopyAccountLogger.Errorf("解析快手响应data失败: %v", err)
			return nil, errors.New("解析快手响应失败")
		}
	}

	return cp, nil
}

// KsSendCurlRequest 发送HTTP请求到快手API
func KsSendCurlRequest(requestURL, method, token string, data interface{}, headers []string, result interface{}) error {
	var req *http.Request
	var err error

	// 处理GET请求参数
	if strings.ToUpper(method) == "GET" && data != nil {
		// 将data转换为查询参数
		params, err := convertToQueryParams(data)
		if err != nil {
			return fmt.Errorf("转换查询参数失败: %w", err)
		}

		if params != "" {
			requestURL = requestURL + "?" + params
		}
	}

	// 创建HTTP请求
	if strings.ToUpper(method) == "POST" {
		// POST请求处理
		jsonData, err := json.Marshal(data)
		if err != nil {
			return fmt.Errorf("JSON序列化失败: %w", err)
		}

		req, err = http.NewRequest(strings.ToUpper(method), requestURL, bytes.NewBuffer(jsonData))
		if err != nil {
			return fmt.Errorf("创建请求失败: %w", err)
		}
	} else {
		// 其他请求方法（如GET）
		req, err = http.NewRequest(strings.ToUpper(method), requestURL, nil)
		if err != nil {
			return fmt.Errorf("创建请求失败: %w", err)
		}
	}

	// 设置HTTP版本
	req.Proto = "HTTP/1.1"
	req.ProtoMajor = 1
	req.ProtoMinor = 1

	// 设置默认头部
	defaultHeaders := []string{
		"User-Agent: Go-http-client/1.1",
	}

	// 合并传入的头部和默认头部
	allHeaders := append(defaultHeaders, headers...)

	// 处理POST请求的特殊头部
	if strings.ToUpper(method) == "POST" {
		allHeaders = append(allHeaders, "Content-Type:application/json")
		allHeaders = append(allHeaders, "Access-Token:"+token)
	}

	// 应用头部到请求
	for _, header := range allHeaders {
		parts := strings.SplitN(header, ":", 2)
		if len(parts) == 2 {
			req.Header.Set(strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1]))
		}
	}

	// 创建HTTP客户端（跳过SSL验证，与原PHP代码保持一致）
	client := &http.Client{
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
		},
	}

	// 发送请求
	resp, err := client.Do(req)
	if err != nil {
		return fmt.Errorf("发送请求失败: %w (URL: %s)", err, requestURL)
	}
	defer resp.Body.Close()

	// 读取响应
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return fmt.Errorf("读取响应失败: %w", err)
	}

	// 解析响应为结构体
	err = json.Unmarshal(body, &result)
	if err != nil {
		ksCopyAccountLogger.Errorf("解析快手响应失败：%s, 错误: %v", string(body), err)
		return fmt.Errorf("解析响应失败: %w", err)
	}

	// 记录日志（如果需要）
	ksCopyAccountLogger.Infof("快手返回结果：%s", string(body))

	return nil
}

// convertToQueryParams 将数据转换为查询参数
func convertToQueryParams(data interface{}) (string, error) {
	if data == nil {
		return "", nil
	}

	// 如果data是map[string]interface{}类型
	if params, ok := data.(map[string]interface{}); ok {
		values := url.Values{}
		for key, value := range params {
			if str, ok := value.(string); ok {
				values.Add(key, str)
			} else if num, ok := value.(int); ok {
				values.Add(key, fmt.Sprintf("%d", num))
			} else if num, ok := value.(float64); ok {
				values.Add(key, fmt.Sprintf("%g", num))
			} else if b, ok := value.(bool); ok {
				if b {
					values.Add(key, "1")
				} else {
					values.Add(key, "0")
				}
			} else {
				// 尝试转换为字符串
				jsonValue, err := json.Marshal(value)
				if err != nil {
					return "", err
				}
				values.Add(key, string(jsonValue))
			}
		}
		return values.Encode(), nil
	}

	// 如果data是字符串类型
	if str, ok := data.(string); ok {
		return str, nil
	}

	// 其他类型尝试JSON序列化
	jsonBytes, err := json.Marshal(data)
	if err != nil {
		return "", err
	}
	return string(jsonBytes), nil
}

// analyzeContent 解析内容为广告主信息数组
func (s *DeftHandCopyAccountService) analyzeContent(content []string) ([]KsAccount, error) {
	// 初始化结果变量
	var subjectName string
	var accountIDs []string
	var copyNumber string
	var username string
	var openId string
	var userId string
	var code string
	var email string

	// 编译正则表达式（支持中文逗号、顿号）
	sepRegex, err := regexp.Compile(`[,，、]`)
	if err != nil {
		ksCopyAccountLogger.Error("广告主ID分隔符正则表达式编译失败", err)
		return nil, fmt.Errorf("正则表达式编译失败: %w", err)
	}

	// 遍历内容行
	for _, line := range content {
		// 项目名称
		if strings.HasPrefix(line, "项目名称:") {
			subjectName = strings.TrimSpace(strings.TrimPrefix(line, "项目名称:"))
		}
		// 广告主ID
		if strings.HasPrefix(line, "广告主ID:") {
			raw := strings.TrimPrefix(line, "广告主ID:")
			ids := sepRegex.Split(raw, -1)
			for _, id := range ids {
				trimmed := strings.TrimSpace(id)
				if trimmed != "" {
					accountIDs = append(accountIDs, trimmed)
				}
			}
		}
		// 复制数量
		if strings.HasPrefix(line, "复制数量:") {
			copyNumber = strings.TrimSpace(strings.TrimPrefix(line, "复制数量:"))
		}
		// 媒介名字
		if strings.HasPrefix(line, "媒介名字:") {
			username = strings.TrimSpace(strings.TrimPrefix(line, "媒介名字:"))
		}
		// 开户后台ID
		if strings.HasPrefix(line, "开户后台ID:") {
			openId = strings.TrimSpace(strings.TrimPrefix(line, "开户后台ID:"))
		}
		// userid
		if strings.HasPrefix(line, "userid:") {
			userId = strings.TrimSpace(strings.TrimPrefix(line, "userid:"))
		}
		// 验证码
		if strings.HasPrefix(line, "验证码:") {
			code = strings.TrimSpace(strings.TrimPrefix(line, "验证码:"))
		}
		// 邮箱
		if strings.HasPrefix(line, "邮箱:") {
			email = strings.TrimSpace(strings.TrimPrefix(line, "邮箱:"))
		}
	}
	// 验证复制数量
	if copyNumber == "" {
		return nil, fmt.Errorf("未找到复制数量")
	}

	// 媒介名称
	if username == "" {
		return nil, fmt.Errorf("未找到媒介")
	}

	num, err := strconv.Atoi(copyNumber)
	if err != nil {
		return nil, fmt.Errorf("复制数量必须为整数: %v", err)
	}
	if num < 1 {
		return nil, fmt.Errorf("复制数量不能小于1")
	}

	if len(accountIDs) < 0 {
		return nil, fmt.Errorf("广告主ID不能为空")
	}

	// 构建结果
	var result []KsAccount
	for _, accountID := range accountIDs {
		result = append(result, KsAccount{
			SubjectName: subjectName,
			AccountID:   accountID,
			CopyNumber:  copyNumber,
			Username:    username,
			OpenId:      openId,
			UserId:      userId,
			Code:        code,
			Email:       email,
		})
	}

	// 空数据警告（可选）
	if len(result) == 0 {
		ksCopyAccountLogger.Warn("未解析到有效广告主ID")
		return nil, fmt.Errorf("未解析到有效广告主ID")
	}

	return result, nil
}

func getDeftHandToken(serveAccountID string) (string, error) {
	urlToken := fmt.Sprintf("https://operator.ecoremedia.net/kuaishou/token?serve_account_id=%s", serveAccountID)

	resp, err := http.Get(urlToken)
	if err != nil {
		ksCopyAccountLogger.Errorf("获取Token请求失败: %v", err)
		return "", fmt.Errorf("获取Token失败，请联系工程师")
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		ksCopyAccountLogger.Errorf("读取Token响应失败: %v", err)
		return "", fmt.Errorf("获取Token失败，请联系工程师")
	}

	var tokenResponse getKsBackgroundToken
	err = json.Unmarshal(body, &tokenResponse)
	if err != nil {
		ksCopyAccountLogger.Errorf("解析Token响应失败: %v", err)
		return "", fmt.Errorf("获取Token失败，请联系工程师")
	}

	// 检查返回数据的有效性
	if tokenResponse.Code != 0 || tokenResponse.Data.Token == "" {
		ksCopyAccountLogger.Errorf("获取Token失败，错误码: %d, 错误信息: %s", tokenResponse.Code, tokenResponse.Msg)
		return "", fmt.Errorf("获取Token失败，请联系工程师")
	}

	return tokenResponse.Data.Token, nil
}
